from pyecharts.charts import Bar,Line,Grid
import pyecharts.options as opts
import pandas as pd
from jili.trade.constants import bs
class return_chart:
    def __init__(self):
        self.grad_index = 1
        self.grid = None
        self.sub_charts=[]
        self.main_net=None
        self.x=[]
        self.havedrawdown=False
    def prepare_data(self,data,field=None):
        x = []
        y = []
        if isinstance(data, dict):
            if field:
                for k,v in data.items():
                    x.append(str(k)[:10])
                    y.append(v[field])
            else:
                for i in data.keys():
                    x.append(str(i)[:10])
                y = list(data.values())
        elif isinstance(data, pd.DataFrame):
            if field:
                for i in list(data.index):
                    x.append(str(i)[:10])
                y = data[field].tolist()
        elif isinstance(data, pd.Series):
            for i in list(data.index):
                x.append(str(i)[:10])
            y = data.tolist()
        elif isinstance(data, list):
            if len(data) == 2:
                if isinstance(data[0],list):
                    x = data[0]
                    y = data[1]
            else:
                if field:
                    for i in data:
                        x.append(str(i["timekey"])[:10])
                        y.append(i[field])
                else:
                    y=data
        return x,y
    def add_net(self,data,name="净值",field="net"):
        """
        Args:
            data:
            dict:{},key=timekey,value=net
            list:[] [x:list,y:list]
            DataFrame:  "timekey",   "net"

        Returns:None
        """
        x,y=self.prepare_data(data,field=field)
        if not self.main_net:
            self.main_net=Line()
            if x:
                self.x=x
                self.main_net.add_xaxis(xaxis_data=x)
                self.main_net.add_yaxis(
                    series_name=name,
                    y_axis=y,
                    is_smooth=True, is_symbol_show=False,
                )
        else:
            if x:
                self.main_net.add_yaxis(
                    series_name=name,
                    y_axis=y,
                    is_smooth=True, is_symbol_show=False,
                )
                if not self.x:
                    self.x = x
    def __set_subchart_globle_opt(self,chart):
        chart.set_global_opts(
            xaxis_opts=opts.AxisOpts(
                type_="category",
                is_scale=True,
                grid_index=self.grad_index,
                boundary_gap=False,
                axisline_opts=opts.AxisLineOpts(is_on_zero=False),
                axistick_opts=opts.AxisTickOpts(is_show=False),
                splitline_opts=opts.SplitLineOpts(is_show=False),
                axislabel_opts=opts.LabelOpts(is_show=False),
                # split_number=20,
                min_="dataMin",
                max_="dataMax",
            ),
            yaxis_opts=opts.AxisOpts(
                grid_index=self.grad_index,
                #is_scale=True,
                #split_number=2,
                axislabel_opts=opts.LabelOpts(is_show=True),
                axisline_opts=opts.AxisLineOpts(is_show=True),
                axistick_opts=opts.AxisTickOpts(is_show=True),
                splitline_opts=opts.SplitLineOpts(is_show=True),
            ),
            legend_opts=opts.LegendOpts(is_show=False),
        )
        return chart
    def __set_globle_opt(self,chart):
        chart.set_global_opts(
            xaxis_opts=opts.AxisOpts(
                type_="category",
                is_scale=True,
                grid_index=self.grad_index,
                boundary_gap=False,
                axisline_opts=opts.AxisLineOpts(is_on_zero=False),
                axistick_opts=opts.AxisTickOpts(is_show=False),
                splitline_opts=opts.SplitLineOpts(is_show=False),
                axislabel_opts=opts.LabelOpts(is_show=False),
                # split_number=20,
                min_="dataMin",
                max_="dataMax",
            ),
            yaxis_opts=opts.AxisOpts(
                grid_index=self.grad_index,
                #is_scale=True,
                #split_number=2,
                axisline_opts=opts.AxisLineOpts(is_on_zero=False),
                axistick_opts=opts.AxisTickOpts(is_show=False),
                splitline_opts=opts.SplitLineOpts(is_show=False),
                axislabel_opts=opts.LabelOpts(is_show=False),
            ),
            legend_opts=opts.LegendOpts(is_show=False),
        )
        return chart
    def __add_drawdown(self,data,name="回撤",field="drawdown"):
        """
        Args:
            data:
            dict:{},key=timekey,value=drawdown
            list:[] [x:list,y:list]
            DataFrame:  "timekey",   "drawdown"

        Returns:None
        """
        x,y=self.prepare_data(data,field=field)
        if x:
            """
            self.main_net.add_yaxis(series_name=name, y_axis=y, yaxis_index=1,is_smooth=True,is_symbol_show=False,
                           areastyle_opts=opts.AreaStyleOpts(opacity=0.5),
                           linestyle_opts=opts.LineStyleOpts(),
                           label_opts=opts.LabelOpts(is_show=False),
                           )
            self.main_net.extend_axis(
                yaxis=opts.AxisOpts(
                    name="drawdown",
                    name_location="start",
                    type_="value",
                    max_=1,
                    is_inverse=True,
                    #axistick_opts=opts.AxisTickOpts(is_show=True),
                    #splitline_opts=opts.SplitLineOpts(is_show=True)
                ))
            """
            self.main_net.add_yaxis(
                series_name="降雨量",
                y_axis=y,
                yaxis_index=1,
                areastyle_opts=opts.AreaStyleOpts(opacity=0.5),
                linestyle_opts=opts.LineStyleOpts(),
                label_opts=opts.LabelOpts(is_show=False),
            )
            self.main_net.extend_axis(
                yaxis=opts.AxisOpts(
                    name="降雨量(mm)",
                    name_location="start",
                    type_="value",
                    max_=1,
                    is_inverse=True,
                    axistick_opts=opts.AxisTickOpts(is_show=True),
                    splitline_opts=opts.SplitLineOpts(is_show=True),
                )
            )
            self.havedrawdown=True
    def add_sub_Bar(self,data,name="pl",field="pl"):
        """
                Args:
                    data:
                    dict:{},orders: key=timekey,value=pl
                    list:[] [x:list,y:list]   2个判断为x,y 大于2个判断为order list
                    DataFrame:  "timekey",   "pl"

                Returns:None
                """
        x,y=self.prepare_data(data,field=field)
        if y:
            chart = Bar()
            chart.add_xaxis(self.x)
            chart.add_yaxis(name, y,label_opts = opts.LabelOpts(is_show=False))
            self.__set_subchart_globle_opt(chart)
            self.sub_charts.append(chart)
            self.grad_index = self.grad_index + 1
    def add_sub_Bar_nozoom(self,data,name="",field=None):
        x, y = self.prepare_data(data, field=field)
        chart = Bar()
        chart.add_xaxis(x)
        chart.add_yaxis(name, y, label_opts=opts.LabelOpts(is_show=False))
        self.__set_subchart_globle_opt(chart)
        self.sub_charts.append(chart)
    def draw(self,width="1800px"):
        #xaxislen = 100 * (len(self.x) - 100) / len(self.x)
        x_indexs = list(range(self.grad_index))
        datazoom_opts = opts.DataZoomOpts(range_start=0, range_end=100, type_='inside',
                                          xaxis_index=x_indexs,
                                          orient="both")
        self.main_net.set_global_opts(title_opts=opts.TitleOpts(title="绩效分析"),
                                   datazoom_opts=datazoom_opts,
                                   tooltip_opts=opts.TooltipOpts(trigger="axis", axis_pointer_type="cross"),
                                      axispointer_opts=opts.AxisPointerOpts(
                                          is_show=True,
                                          link=[{"xAxisIndex": "all"}],
                                          label=opts.LabelOpts(background_color="#777"),
                                      ),
                                      brush_opts=opts.BrushOpts(
                                          x_axis_index="all",
                                          brush_link="all",
                                          out_of_brush={"colorAlpha": 0.1},
                                          brush_type="lineX",
                                      ),
                                      xaxis_opts=opts.AxisOpts(
                                          type_="category",
                                          axisline_opts=opts.AxisLineOpts(is_on_zero=False),
                                          axistick_opts=opts.AxisTickOpts(is_show=False),
                                          splitline_opts=opts.SplitLineOpts(is_show=False),
                                          axislabel_opts=opts.LabelOpts(is_show=False)
                                      ),
                                      yaxis_opts=opts.AxisOpts(
                                          type_="value",
                                          is_scale=True,
                                      ),

                                      )
        #self.__set_globle_opt(self.main_net)
        height0 = 600 + len(self.sub_charts) * 180 + (len(self.sub_charts) + 1) * 10
        grid_chart = Grid(
            init_opts=opts.InitOpts(
                width=width,
                height=str(height0) + "px",
                animation_opts=opts.AnimationOpts(animation=False),
            )
        )
        # h0=600/height0
        grid_chart.add(
            self.main_net,
            grid_opts=opts.GridOpts(pos_left="3%", pos_right="1%", height="500px"),
        )
        h0 = 500 + 75 + 10
        for chart in self.sub_charts:
            grid_chart.add(
                chart,
                grid_opts=opts.GridOpts(pos_left="3%", pos_right="1%", pos_top=str(h0) + "px", height="180px"),
            )
            h0 = h0 + 180 + 10
        return grid_chart
if __name__=="__main__":
    from jili.core import load
    a = load(r"F:\qjs\data\2019\bar_ta")
    """
    #from jili.tool.state import report_path
    #from jili.pos.assets_returns import asset_returns
    from jili.pos.pms import performance
    
    assets=asset_returns()
    for k,v in a["close.1m"].to_dict().items():
        tk=pd.to_datetime(k)
        assets.setdata(tk,v)
    #p=performance()
    """
    a["net"]=a["close.1m"]
    a["return"]=a["close.1m"].diff()
    a["return"]=a["return"]/a["close.1m"]
    a["drawdown"]=a["close.1m"]
    a["pl"]=a["close.1m"].diff()
    c = return_chart()
    c.add_net(a)
    #c.add_drawdown(a)
    #c.add_pl_amount(a)
    chart = c.draw("1650px")
    chart.render(r"F:\qjs\reporthtml\test_return.html")
    #print(report_path.jion("test_kline.html"))